
#include <QGraphicsLinearLayout>
#include <QGraphicsProxyWidget>
#include <QGraphicsSceneResizeEvent>
#include <QLabel>

#include "wppagegraphicslistitem.h"
#include "wppagegraphicslist.h"
#include "WPData.h"
#include "BlogView.h"
#include "PopupMenu.h"
#include "wpconfirmdialog.h"

#include "buttongraphicsproxy.h"
#include "ShadowGraphicsItem.h"
#include "ListTitle.h"

WPPageGraphicsList::WPPageGraphicsList(
        const QGraphicsView& aGraphicsView,BlogView* aBlogView, PannableView* aPannableView
    ) : 
        WPGraphicsList(aBlogView, aGraphicsView, aPannableView)
{
    // TODO find a proper way to align menu icon and text side by side.
    iActionOpen = new QAction(iThemeData.GetContextIcon(ThemeData::EOpen),tr("Open"), this);
    iActionEdit = new QAction(iThemeData.GetContextIcon(ThemeData::EEdit),tr("Edit"), this);
    iActionDelete = new QAction(iThemeData.GetContextIcon(ThemeData::ERemove),tr("Delete"), this);

    connect(iActionOpen, SIGNAL(triggered(bool)), this, SLOT(Open()));
    connect(iActionEdit, SIGNAL(triggered(bool)), this, SLOT(Edit()));
    connect(iActionDelete, SIGNAL(triggered(bool)), this, SLOT(Delete()));

    iNewPageButton = new ButtonGraphicsProxy(tr("Write new page"), this);
    iNewPageButton->button()->setObjectName("newPageButton");
    iNewPageButton->button()->setStyleSheet(iThemeData.iListButtonQss);
    connect(iNewPageButton->button(), SIGNAL(clicked(bool)), aBlogView, SLOT(ShowWriteNewPageView()));

    iDraftsLabel = new ListTitle(this, iThemeData);
    iDraftsTopShadow = new ShadowGraphicsItem(ShadowGraphicsItem::Top, this);
    iDraftsBottomShadow = new ShadowGraphicsItem(ShadowGraphicsItem::Bottom, this);
    
    iPagesLabel = new ListTitle(this, iThemeData);
    iPagesTopShadow = new ShadowGraphicsItem(ShadowGraphicsItem::Top, this);
    iPagesBottomShadow = new ShadowGraphicsItem(ShadowGraphicsItem::Bottom, this);
    
    iLayout->addItem(iNewPageButton);
    
    iLayout->addItem(iDraftsLabel);
    iLayout->addItem(iDraftsTopShadow);
    iDraftsLayout = AddLayout();
    iLayout->addItem(iDraftsBottomShadow);
    
    iLayout->addItem(iPagesLabel);
    iLayout->addItem(iPagesTopShadow);
    iPagesLayout = AddLayout();
    iLayout->addItem(iPagesBottomShadow);
 
    UpdateLabels();
}

WPPageGraphicsList::~WPPageGraphicsList()
{

}

void WPPageGraphicsList::PopulatePopupMenuForCurrentItem(PopupMenu* aPopupMenu)
{
    // XXX Create page viewing view
	//aPopupMenu->addAction(iActionOpen);
	//aPopupMenu->setActiveAction(iActionOpen);
	aPopupMenu->addAction(iActionEdit);
	aPopupMenu->setActiveAction(iActionEdit);
	aPopupMenu->addAction(iActionDelete);
}

void WPPageGraphicsList::AddPage(WPPage aPage)
{
    QStringList list;

    if (aPage->IsLocal())
        list << "Local draft";

    list << WPNetworkEngine::LocalizedTime(aPage->iDateCreated);

    WPPageGraphicsListItem* item = new WPPageGraphicsListItem(aPage, iBusyIndicator, iThemeData);
    connect(item, SIGNAL(Selected(WPGraphicsListItem*)), this, SLOT(ShowContextMenu(WPGraphicsListItem*)));
    
    if(aPage->IsDraft()) {
        OrderedInsert(*iDraftsLayout, *item);
    } else {
        OrderedInsert(*iPagesLayout, *item);
    }
}

void WPPageGraphicsList::RemovePage (WPPage aPage)
{
    WPPageGraphicsListItem * item = 0;
            
    item = RemoveFromLayout(*iDraftsLayout, aPage);
    if(!item) { item = RemoveFromLayout(*iPagesLayout, aPage); }
    
    delete item;
    UpdateLabels();
}

void WPPageGraphicsList::Open()
{
    qDebug("WP::WPPageGraphicsList::Open");
    if(CurrentItem())
        emit OpenClicked(CurrentItem()->GetPage());
}

void WPPageGraphicsList::Edit()
{
    qDebug("WP::WPPageGraphicsList::Edit");
    if(CurrentItem())
        emit EditClicked(CurrentItem()->GetPage());
}

void WPPageGraphicsList::Delete()
{
    WP_CONFIRM_AND_RETURN_ON_FALSE(0)

    qDebug("WP::WPPageGraphicsList::Delete");
    if(CurrentItem())
        CurrentItem()->GetPage()->Delete();
}

void WPPageGraphicsList::UpdatePageData(const WPDataBlog& aBlog)
{   
    if(iCurrentBlog) {
        disconnect(iCurrentBlog, NULL, this, NULL);
    }
    iCurrentBlog = const_cast<WPDataBlog *>(&aBlog);
    
    ClearLayout(*iDraftsLayout);
    ClearLayout(*iPagesLayout);
    
    QListIterator<WPPage> pages(aBlog.GetPages());
    while (pages.hasNext()) {
        WPPage page = pages.next();
        AddPage(page);
    }
    
    // signals
   connect(
      &aBlog,  SIGNAL(PageAdded(WPPage)), 
      this,    SLOT(PageAdded(WPPage))
   );
   connect(
      &aBlog,  SIGNAL(PageChanged(WPPage)), 
      this,    SLOT(PageChanged(WPPage))
   );
   connect(
      &aBlog,  SIGNAL(PageRemoved(WPPage)), 
      this,    SLOT(PageRemoved(WPPage))
   );
    
    UpdateLabels();
}

void WPPageGraphicsList::PageChanged(WPPage aPage)
{
    qDebug("WPPageGraphicsList::PageChanged");

    // cycle
    RemovePage(aPage);
    AddPage(aPage);
    
    UpdateLabels();
}

void WPPageGraphicsList::PageRemoved(WPPage aPage)
{
    qDebug("WPPageGraphicsList::PageRemoved");

    RemovePage(aPage);
    UpdateLabels();
}

void WPPageGraphicsList::PageAdded(WPPage aPage)
{
    qDebug("WPPageGraphicsList::PageAdded");

    AddPage(aPage);
    UpdateLabels();
}

void WPPageGraphicsList::UpdateLabels()
{
    int drafts = iDraftsLayout->count();
    SubLayout draftsLayout(iDraftsLabel, iDraftsTopShadow, iDraftsLayout, iDraftsBottomShadow);
    if (drafts) {
        iDraftsLabel->setText(tr("Drafts") + " (" + QString::number(drafts) + ')');
        ShowSubLayout(draftsLayout, iNewPageButton);
    } else {
        HideSubLayout(draftsLayout);
    }

    int pages = iPagesLayout->count();
    SubLayout pagesLayout(iPagesLabel, iPagesTopShadow, iPagesLayout, iPagesBottomShadow);
    if (pages) {
        iPagesLabel->setText(tr("Pages") + " (" + QString::number(pages) + ')');

        LayoutItemList insertPoints;
        insertPoints << iDraftsBottomShadow << iNewPageButton;
        ShowSubLayout(pagesLayout, insertPoints);
    } else {
        HideSubLayout(pagesLayout);
    }
}

void WPPageGraphicsList::OrderedInsert(QGraphicsLinearLayout & layout, WPPageGraphicsListItem & item)
{
    int i;
    for(i = 0; i < layout.count(); ++i) {
        WPPageGraphicsListItem * listItem = LayoutToListItem(layout.itemAt(i));
        if(*listItem < item) { break; }
    }
    layout.insertItem(i, &item);
}

WPPageGraphicsListItem * WPPageGraphicsList::RemoveFromLayout(QGraphicsLinearLayout & layout, WPPage page)
{
    for(int i = 0; i < layout.count(); ++i) {
        WPPageGraphicsListItem * item = LayoutToListItem(layout.itemAt(i));
        if(item->GetPage() == page) {
            IteratorGuard itGuard(*this, item);
            layout.removeAt(i);
            return item;
        }
    }
    return 0;
}

bool WPPageGraphicsList::IsFocusable(QGraphicsLayoutItem * item)
{
    QGraphicsItem * gItem = item->graphicsItem();
    return (WPGraphicsList::IsListItem(gItem) || gItem == iNewPageButton); 
}

